using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LightCAD.Three
{

    public class BufferGeometryLoader : Loader<BufferGeometry>
    {

        public BufferGeometryLoader(LoadingManager manager = null)
           : base(manager)
        {
        }

        public BufferGeometry load(string url, Action<BufferGeometry> onLoad = null, onProcessDelegate onProgress = null, onErrorDelegate onError = null)
        {

            var loader = new FileLoader(this.manager);
            loader.setPath(this.path);
            loader.setRequestHeader(this.requestHeader);
            loader.setWithCredentials(this.withCredentials);
            BufferGeometry geo = null;
            loader.load(url, (json) =>
            {

                try
                {
                    //geo = this.parse(JObject.Parse((string)json));
                    if (onLoad != null)
                        onLoad(geo);

                }
                catch (Exception err)
                {

                    if (onError != null)
                    {
                        onError(new ErrorEvent { exception = err });
                    }
                    else
                    {
                        console.error(err);
                    }

                    this.manager.itemError(url);

                }

            }, onProgress, onError);

            return geo;
        }

        //public BufferGeometry parse(JObject json)
        //{

        //    var interleavedBufferMap = new JsObj<InterleavedBuffer>();
        //    var arrayBufferMap = new JsObj<JArray>();


        //    Array getTypedArray(string type, JArray jarr)
        //    {

        //        if (type == "Uint32Array" || type == "Uint16Array")
        //        {
        //            var t = new int[jarr.Count];
        //            for (var i = 0; i < jarr.Count; i++) t[i] = (int)jarr[i];
        //            return t;
        //        }
        //        else if (type == "Float32Array")
        //        {
        //            var t = new double[jarr.Count];
        //            for (var i = 0; i < jarr.Count; i++) t[i] = (double)jarr[i];
        //            return t;
        //        }
        //        return null;
        //    }

        //    InterleavedBuffer getInterleavedBuffer(JObject jobj, string uuid)
        //    {

        //        if (interleavedBufferMap[uuid] != null) return interleavedBufferMap[uuid];

        //        var interleavedBuffers = (JObject)jobj["interleavedBuffers"];
        //        var interleavedBuffer = (JObject)interleavedBuffers[uuid];

        //        var buffer = getArrayBuffer(jobj, (string)interleavedBuffer["buffer"]);

        //        var array = getTypedArray((string)interleavedBuffer["type"], buffer);
        //        var ib = new InterleavedBuffer((double[])array, (int)interleavedBuffer["stride"]);
        //        ib.uuid = (string)interleavedBuffer["uuid"];

        //        interleavedBufferMap[uuid] = ib;

        //        return ib;

        //    }

        //    JArray getArrayBuffer(JObject jobj, string uuid)
        //    {

        //        if (arrayBufferMap[uuid] != null) return arrayBufferMap[uuid];

        //        var arrayBuffers = json["arrayBuffers"];
        //        var arrayBuffer = (JArray)arrayBuffers[uuid];

        //        arrayBufferMap[uuid] = arrayBuffer;

        //        return arrayBuffer;

        //    }


        //    JsObj<object> getUserData(JToken token)
        //    {
        //        var obj = getJToken(token);
        //        if (obj is JsObj<object>)
        //            return obj as JsObj<object>;
        //        else
        //            return new JsObj<object> { { "value", obj } };
        //    }
        //    var isIBG = json["isInstancedBufferGeometry"] == null ? false : (bool)json["isInstancedBufferGeometry"];
        //    var geometry = isIBG ? new InstancedBufferGeometry() : new BufferGeometry();

        //    var index = json["data"]["index"];

        //    if (index != null)
        //    {

        //        var typedArray = getTypedArray((string)index["type"], (JArray)index["array"]);
        //        geometry.setIndex(new BufferAttribute(typedArray, 1));

        //    }

        //    var attributes = (JObject)json["data"]["attributes"];

        //    foreach (var item in attributes)
        //    {

        //        var attribute = item.Value;
        //        BufferAttribute bufferAttribute;

        //        var isIBA = json["isInterleavedBufferAttribute"] == null ? false : (bool)json["isInterleavedBufferAttribute"];
        //        if (isIBA)
        //        {

        //            var interleavedBuffer = getInterleavedBuffer((JObject)json["data"], (string)attribute["data"]);
        //            bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, (int)attribute["itemSize"], (int)attribute["offset"], (bool)attribute["normalized"]);

        //        }
        //        else
        //        {
        //            var isInstBA = attribute["isInstancedBufferAttribute"] == null ? false : (bool)attribute["isInstancedBufferAttribute"];
        //            var normalized = attribute["normalized"] == null ? false : (bool)attribute["normalized"];

        //            var typedArray = getTypedArray((string)attribute["type"], (JArray)attribute["array"]);
        //            if (isInstBA)
        //                bufferAttribute = new InstancedBufferAttribute((double[])typedArray, (int)attribute["itemSize"], normalized);
        //            else
        //                bufferAttribute = new BufferAttribute(typedArray, (int)attribute["itemSize"], normalized);

        //        }

        //        if (attribute["name"] != null) bufferAttribute.name = (string)attribute["name"];
        //        if (attribute["usage"] != null) bufferAttribute.setUsage((int)attribute["usage"]);

        //        var updateRange = attribute["updateRange"];
        //        if (updateRange != null)
        //        {

        //            bufferAttribute.updateRange.offset = (int)updateRange["offset"];
        //            bufferAttribute.updateRange.count = (int)updateRange["count"];

        //        }

        //        geometry.setAttribute(item.Key, bufferAttribute);

        //    }

        //    var morphAttributes = json["data"]["morphAttributes"];

        //    if (morphAttributes != null)
        //    {

        //        foreach (var item in (morphAttributes as JObject))
        //        {

        //            var attributeArray = (JArray)item.Value;

        //            var array = new JsArr<BufferAttribute>();

        //            for (int i = 0, il = attributeArray.Count; i < il; i++)
        //            {

        //                var attribute = attributeArray[i];
        //                BufferAttribute bufferAttribute;

        //                if ((bool)attribute["isInterleavedBufferAttribute"])
        //                {

        //                    var interleavedBuffer = getInterleavedBuffer((JObject)json["data"], (string)attribute["data"]);
        //                    bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, (int)attribute["itemSize"], (int)attribute["offset"], (bool)attribute["normalized"]);

        //                }
        //                else
        //                {

        //                    var typedArray = getTypedArray((string)attribute["type"], (JArray)attribute["array"]);
        //                    bufferAttribute = new BufferAttribute(typedArray, (int)attribute["itemSize"], (bool)attribute["normalized"]);

        //                }

        //                if (attribute["name"].Type != JTokenType.Undefined) bufferAttribute.name = (string)attribute["name"];
        //                array.push(bufferAttribute);

        //            }

        //            geometry.morphAttributes[item.Key] = array;

        //        }

        //    }

        //    var morphTargetsRelative = json["data"]["morphTargetsRelative"];

        //    if (morphTargetsRelative != null)
        //    {

        //        geometry.morphTargetsRelative = (bool)morphTargetsRelative;

        //    }

        //    var groups = json["data"]["groups"];
        //    if (groups == null)
        //        groups = json["data"]["drawcalls"];
        //    else if (groups == null)
        //        groups = json["data"]["offsets"];

        //    if (groups != null)
        //    {
        //        var grpArr = (JArray)groups;

        //        for (int i = 0, n = grpArr.Count; i != n; ++i)
        //        {

        //            var grp = grpArr[i];

        //            geometry.addGroup((int)grp["start"], (int)grp["count"], (int)grp["materialIndex"]);

        //        }

        //    }

        //    var boundingSphere = json["data"]["boundingSphere"];

        //    if (boundingSphere != null)
        //    {

        //        var center = new Vector3();

        //        if (boundingSphere["center"].Type != JTokenType.Undefined)
        //        {
        //            var arr = getTypedArray("Float32Array", (JArray)boundingSphere["center"]);
        //            center.fromArray((double[])arr);

        //        }

        //        geometry.boundingSphere = new Sphere(center, (double)boundingSphere["radius"]);

        //    }

        //    if (json["name"] != null) geometry.name = (string)json["name"];
        //    if (json["userData"] != null) geometry.userData = getUserData(json["userData"]);

        //    return geometry;

        //}

    }
}
